Bioinfo - Programmer en AWK
Bioinfo - Programmer en AWK
contact: ludwig@univ-brest.fr
AWK est un langage pour traiter des fichiers textes, ligne-par-ligne. La ligne peut être séparée en champs (colonnes ou mots).
Prenez les fichiers d'entrées
mkdir ~/awk
cd ~/awk
cp /home/tludwig/master2ggb/tableawk.tsv .
cp /home/tludwig/s.omalleysbar.txt .
wget http://lysine.univ-brest.fr/~tludwig/master2/tp3/1.variants.vcf
bash1. Un programme simple
Affiche chaque ligne en entrée, sans modification:
cat tableawk.tsv | awk '{print $0}'
bashprintest la fonction qui permet d'afficher du texte.$0signifie toute la ligne
2. Accéder à un champ
cat tableawk.tsv | awk '{print $2}'
bash$isignifie la i colonne
3. Quelques variables globales
cat s.omalleysbar.txt | awk '{print NF}' | sort -n | uniq -c
cat tableawk.tsv | awk '{print NR": "$0}'
bashNF(Number of Fields) indique le nombre de colonne dans la ligne actuelleNR(Number of Reccords) indique le nombre de ligne lu jusqu'à présent
4. Utiliser les variables
cat s.omalleysbar.txt | awk '{print $NF}' | head
bash $NF signifie la dernière colonne (c'est-à-dire la NF
5. BEGIN / END
- La section
BEGIN{}est exécutée intégralement avant de lire la première ligne. - La section
END{}est exécutée intégralement après avec traité la dernière ligne.
cat tableawk.tsv | awk '
BEGIN{
print "Lets-a-gooo"
}
{
print $0
}
END{
print "Il y avait "NR" lignes dans ce fichier."
}'
bash6. Multiples instructions
Les instructions sont séparées par des point-virgules ;
cat tableawk.tsv | awk '
{
print NR;
print $0
}'
bash7. Conditionnelles
if(condition){block}permet d'exécuterblocksiconditionest vrai
cat tableawk.tsv | awk '
{
if($0 ~ "^#"){
print "il y a "NF" colonnes"
}
}'
bash ~ "^#" indique les lignes qui commencent par #
else{block2}permet d'exécuterblock2quandconditionest faux
cat tableawk.tsv | awk '
{
if($0 ~ "^#"){
print "il y a "NF" colonnes"
}
else{
print $0
}
}'
bashOn ne garde que les filles (et l'en-tête)
cat tableawk.tsv | awk '
{
if($0 ~ "^#" || $3 == "F"){
print $0
}
}'
bash8. Définir et utiliser des variables
nom_de_variable = 18ounom_de_variable = "Texte"permet d'assigner une valeur à une variable
cat tableawk.tsv | awk '
BEGIN{
male=0
}
{
if($3 == "M")
{
male=male+1
}
}
END{
print "There are "male" men"
}'
basha = 2 affecte la valeur 2 à la variantab == 3 renvoieTRUEsi la variablebest égale à 3
On peut utiliser une variable dans un calcul
cat tableawk.tsv | awk '
BEGIN{
height=0
}
{
if($0 !~ "^#"){
height=height+$4
}
}
END{
mean=height/(NR-1);
print "mean height: "mean
}'
bash9. Tableaux
x[]indique un tableau du nom dex
cat tableawk.tsv | awk '
BEGIN{
height["M"]=0;
height["F"]=0;
nb["M"]=0;
nb["F"]=0;
}
{
height[$3]=height[$3]+$4;
nb[$3] = nb[$3] + 1;
}
END{
mean["M"]=height["M"]/nb["M"];
mean["F"]=height["F"]/nb["F"];
print "mean height.";
print "for men "mean["M"];
print "for women "mean["F"];
}'
bash- Les cases vides des tableaux contiennent 0. On peut donc simplifier en
cat tableawk.tsv | awk '
{
height[$3]=height[$3]+$4;
nb[$3] = nb[$3] + 1;
}
END{
mean["M"]=height["M"]/nb["M"];
mean["F"]=height["F"]/nb["F"];
print "mean height.";
print "for men "mean["M"];
print "for women "mean["F"];
}'
bash10. Parcourir un tableau
for (variable in tableau){block}permet d'affecter àvariablesuccéssivement chaque clé d'un tableau et d'exécuterblockpour cette clé.
cat tableawk.tsv | awk '
{
if($0 !~ "^#"){
age[$2]=age[$2] + 1;
}
}
END{
for(a in age){
print "number of "a" years old : "age[a];
}
}'
bash11. Un peu de bioinfo ?
On considère le VCF 1.variants.vcf et on veut connaître le première et le dernier variant de chaque chromosome.
- On va évider de traiter les lignes d'en-tête grace à
if($0 !~ "^#") - On va stoquer les variants dans des tableaux
first[]etlast[] - On va parcourir ces tableaux et afficher
- ⚠ On va chercher les minimums et maximum des positions. Les cases vides des tableaux contiennent 0.
||signifie OUif(cond1 || cond2)vérifie quecond1oucond2(ou les deux) est VRAI
cat 1.variants.vcf | awk '
{
if($0 !~ "^#"){
chr=$1;
pos=$2;
if(pos < first[chr] || first[chr] == 0){
first[chr] = pos;
}
if(pos > last[chr]){
last[chr] = pos;
}
}
}
END{
for(chr in last){
print "Chromosome "chr":"first[chr]"-"last[chr];
}
}'
bash12. 😈 Welcome to my world of pain 😈
On veut afficher tous les variants pour lesquels l'enfant est homozyogote et les parents hétérozygotes.
Rappel du format
cat 1.variants.vcf | grep "^#" | tail -1
bashEviter les en-têtes
cat 1.variants.vcf | grep -v "^#" | head
bashOn ne prend que les colonnes qui nous intéressent
- chrom (1)
- pos (2)
- id (3)
- ref (4)
- alt (5)
- enfant (10)
- maman (11)
- papa (12)
cat 1.variants.vcf | grep -v "^#" | head | cut -f-5,10-
bashOn s'intéresse au génotype, mais pas aux annotations qui suivent
On transforme les colonnes en lignes
cat 1.variants.vcf | grep -v "^#" | head | cut -f-5,10- | tr "\t" "\n"
bashOn enlève se qui suit les doubles points :
cat 1.variants.vcf | grep -v "^#" | head | cut -f-5,10- | tr "\t" "\n" | cut -f1 -d':'
bashOn reforme les lignes (il y avait 8 colonnes)
cat 1.variants.vcf | grep -v "^#" | cut -f-5,10- | tr "\t" "\n" | cut -f1 -d':' | paste - - - - - - - - > variants.tsv
cat variants.tsv | head
bashC'est parti
Les génotypes sont dans les colonnes
- enfant : 6
- maman : 7
- papa : 8
On affiche tout
cat variants.tsv | awk '
{
if($6 == "1/1" && $7 == "0/1" && $8 == "0/1")
{
print $0
}
}'
bashSolution alternative pour garder toute la ligne et faire un VCF valide avec en-tête
cat 1.variants.vcf | awk '
{
if($1 ~ "^#"){
print $0
}
if($10 ~ "^1/1" && $11 ~ "^0/1" && $12 ~ "^0/1")
{
print $0
}
}'
bashPour un variant de type 1/1 | 0/1 | 1/2, il faut séparer les chromosomes